// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#ifndef STORAGE_LEVELDB_DB_MEMTABLE_H_
#define STORAGE_LEVELDB_DB_MEMTABLE_H_

#include <string>

#include "db/dbformat.h"
#include "db/skiplist.h"
#include "leveldb/db.h"
#include "util/arena.h"

namespace leveldb
{

    class InternalKeyComparator;
    class MemTableIterator;

    class MemTable
    {
    public:
        // MemTables are reference counted.  The initial reference count
        // is zero and the caller must call Ref() at least once.
        /* Memtable为引用计数。初始引用数量为0，并且调用着必须调用Ref()至少一次。 */
        explicit MemTable(const InternalKeyComparator &comparator);

        /* 删除拷贝构造函数和复制构造函数 */
        MemTable(const MemTable &) = delete;
        MemTable &operator=(const MemTable &) = delete;

        // Increase reference count.
        /* 引用函数 */
        void Ref() { ++refs_; }

        // Drop reference count.  Delete if no more references exist.
        /* 减少引用，如果引用减少至0则删除本对象 */
        void Unref()
        {
            --refs_;
            assert(refs_ >= 0);
            if (refs_ <= 0)
            {
                /* 删除本对象 */
                /* 有关delete this的详解：https://blog.csdn.net/nie2314550441/article/details/76880711 */
                delete this;
            }
        }

        // Returns an estimate of the number of bytes of data in use by this
        // data structure. It is safe to call when MemTable is being modified.
        /* 返回此memtable中的数据字节大小，该值为一个估算值。即使当memtable被修改时，调用这个函数也是安全的。 */
        size_t ApproximateMemoryUsage();

        // Return an iterator that yields the contents of the memtable.
        //
        // The caller must ensure that the underlying MemTable remains live
        // while the returned iterator is live.  The keys returned by this
        // iterator are internal keys encoded by AppendInternalKey in the
        // db/format.{h,cc} module.
        /*  NewIterator返回一个用于遍历memtable中元素的迭代器。调用者必须确保返回的迭代
            器处于活跃状态时，它所属的memtable也必须属于活跃状态。迭代器返回的key值为
            AppendInternalKey以internal key形式编码的。 */
        Iterator *NewIterator();

        // Add an entry into memtable that maps key to value at the
        // specified sequence number and with the specified type.
        // Typically value will be empty if type==kTypeDeletion.
        /* 在memtable中添加一个条目，该条目将key映射到指定sequence number和指定type的value。 */
        void Add(SequenceNumber seq, ValueType type, const Slice &key,
                 const Slice &value);

        // If memtable contains a value for key, store it in *value and return true.
        // If memtable contains a deletion for key, store a NotFound() error
        // in *status and return true.
        // Else, return false.
        /*  如果memtable中包含了一个key，则将其存储在*value内，并返回true.
            如果memtable中包含了一个将要删除的key，在status中存储一个个NotFount()错误，并返回true.
            其他情况，则返回false. */
        bool Get(const LookupKey &key, std::string *value, Status *s);

    private:
        friend class MemTableIterator;
        friend class MemTableBackwardIterator;

        struct KeyComparator
        {
            const InternalKeyComparator comparator;
            /* explicit : 指定构造函数或转换函数 (C++11起)为显式, 即它不能用于隐式转换和复制初始化. */
            explicit KeyComparator(const InternalKeyComparator &c) : comparator(c) {}
            int operator()(const char *a, const char *b) const;
        };

        /* 跳表，存储值的关键数据结构 */
        typedef SkipList<const char *, KeyComparator> Table;

        /* 析构函数私有化，这样只能通过Unref()函数调用来删除本对象。 */
        ~MemTable(); // Private since only Unref() should be used to delete it

        KeyComparator comparator_; //比较器
        int refs_;    //引用计数
        Arena arena_; //内存池
        Table table_; //调表
    };

} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_MEMTABLE_H_
